package comtacti.native.tests;
import utest.Assert;
import haxe.Int32;
import haxe.Int64;
import comtacti.native.InlinedHxcpp;

class TestBasicInlined
{
	private var test:BaseTest;
	
	public function new()
	{
		
	}
	
	public function setup():Void 
	{
		test = new BaseTest();
	}
	
	public function test_StaticVoidFunction():Void 
	{
		BaseTest.voidFunc();
	}
	
	public function test_StaticStringFunction():Void 
	{
		var s = BaseTest.sendMeHello();
		Assert.equals("Hello, World!", s);
	}
	
	public function test_MemberStringFunction():Void 
	{
		var s = test.memberStringFunc();
		Assert.equals("Hello, World!", s);
	}
	
	public function test_Int64Funcion():Void 
	{
		var i = BaseTest.getInt64();
		Assert.is(i, Int64);
		Assert.equals("1234567890123456", Int64.toStr(i));
	}
	
	public function test_Int64AddressOf():Void 
	{
		var i = BaseTest.addressOfString("Hello, World!");
		Assert.is(i, Int64);
	}
}

@:hxinclude(haxe.Int64)
@:hxinclude(haxe.Int32)
class BaseTest implements InlinedHxcpp
{
	public function new():Void 
	{
		
	}
	
	public function memberStringFunc():String 
	{
		return untyped __cpp__("{0}", "Hello, World!");
	}
	
	public static function voidFunc():Void 
	{
		var s:String = null;
		untyped __cpp__("{0} = {1}", s, "Hello, World!");
		Assert.equals(s, "Hello, World!");
	}
	
	public static function sendMeHello():String 
	{
		return untyped __cpp__("{0}", "Hello, World!");
	}
	
	public static inline function addressOfString(s:String):Int64 
	{
		untyped __cpp__("unsigned long long l2 = ((unsigned long long) (void *) &{0})", s);
		untyped __cpp__("int v1 = ((int) ((0xFFFFFFFF00000000LL & l2) >> 32))");
		untyped __cpp__("int v2 = ((int) (0xFFFFFFFFLL & l2))");
		return untyped __cpp__("{0}", Int64.make(Int32.ofInt(v1), Int32.ofInt(v2) ));
	}
	
	public static function getInt64():Int64 
	{
		untyped __cpp__("unsigned long long l2 = 1234567890123456LL", s);
		untyped __cpp__("int v1 = ((int) ((0xFFFFFFFF00000000LL & l2) >> 32))");
		untyped __cpp__("int v2 = ((int) (0xFFFFFFFFLL & l2))");
		return untyped __cpp__("{0}", Int64.make(Int32.ofInt(v1), Int32.ofInt(v2) ));
	}
}